﻿using System;
using System.Threading.Tasks;
using Missbot.Common;
using Missbot.Service.WebSocket;
using Newtonsoft.Json;

namespace Missbot.Core
{
    /// <summary>
    /// WS管理器
    /// </summary>
    public class WSMgr : ISingleton
    {
        private WSClient Client;

        /// <summary>
        /// 接收消息处理回调
        /// </summary>
        private Action<string> MsgReceivedCallback;

        private static ILogSvc ILogSvc => AutofacSvc.Resolve<ILogSvc>();

        private static InstanceConfig InstanceConfig => Configger<AIConfigBase>.AIConfig.Instance;
        
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="MsgReceivedCallback"></param>
        /// <returns></returns>
        public async Task InitAsync(Action<string> MsgReceivedCallback)
        {
            this.MsgReceivedCallback = MsgReceivedCallback;
            var url = $"wss://{InstanceConfig.LocalHost}/streaming?i={InstanceConfig.I}";

            do
            {
                Client = new WSClient(url, MsgReceivedCallback, OnClose);
                if (await Client.Connect())
                {
                    break;
                }
                
                ILogSvc.Log("WS Reconnecting...");
                await Task.Delay(2000);
            } while (true);
                
            await ListenToLocalTimelineAsync();
            await ListenToGlobalTimelineAsync();
            await ListenToMainAsync();
        }
        
        /// <summary>
        /// 监听本地时间线
        /// </summary>
        /// <returns></returns>
        private async Task ListenToLocalTimelineAsync()
        {
            var cntBody = new {type = "connect", body = new {channel = "localTimeline", id = "local", pong = true}};
            await Client.SendAsync(JsonConvert.SerializeObject(cntBody));
        }

        /// <summary>
        /// 监听全局时间线
        /// </summary>
        /// <returns></returns>
        private async Task ListenToGlobalTimelineAsync()
        {
            var cntBody = new {type = "connect", body = new {channel = "globalTimeline", id = "global", pong = true}};
            await Client.SendAsync(JsonConvert.SerializeObject(cntBody));
        }

        /// <summary>
        /// 监听主WS
        /// </summary>
        /// <returns></returns>
        private async Task ListenToMainAsync()
        {
            var cntBody = new {type = "connect", body = new {channel = "main", id = "main", pong = true}};
            await Client.SendAsync(JsonConvert.SerializeObject(cntBody));
        }

        /// <summary>
        /// WS关闭事件
        /// </summary>
        private void OnClose()
        {
            Task.Run(async () => await InitAsync(this.MsgReceivedCallback));
        }
    }
}